package main

import (
	"fmt"
	"math"
)

// 从 point.go 开始（第 10.1 节的练习）：
// 使用方法来实现 Abs() 和 Scale()函数，Point 作为方法的接收者类型。
// 也为 Point3 和 Polar 实现 Abs() 方法。完成了 point.go 中同样的事情，只是这次通过方法。

type Point struct {
	X, Y float64
}

type Point3 struct {
	X, Y, Z float64
}

// params R 半径
type Polar struct {
	R, T float64
}

func (p Point) Abs() float64 {
	return math.Sqrt(p.X*p.X + p.Y*p.Y)
}

func (p *Point) Scale(f float64) {
	p.X *= f
	p.Y *= f
}

func (p Point3) Abs() float64 {
	return math.Sqrt(p.X*p.X + p.Y*p.Y + p.Z*p.Z)
}

func (p Polar) Abs() float64 {
	return p.R
}

func (p Point) Polar() *Polar {
	po := new(Polar)
	po.R = p.Abs()
	po.T = math.Atan2(p.X, p.Y)
	return po
}

func main() {
	p3 := &Point3{1.0, 2.0, 3.0}
	fmt.Printf("p3 %v Abs is: %f\n", p3, p3.Abs())

	p := new(Point)
	p.X = 3
	p.Y = 4
	fmt.Printf("p %v to Polar: %v \n", p, p.Polar())
}
